// compose 的实现
function compose(...funcs) {
    return funcs.reduce((a, b) => (...args) => a(b(...args)));
}

// 假设我们有三个简单的中间件函数
const middleware1 = next => action => {
    console.log('middleware1 开始');
    const result = next(action);
    console.log('middleware1 结束');
    return result;
};

const middleware2 = next => action => {
    console.log('middleware2 开始');
    const result = next(action);
    console.log('middleware2 结束');
    return result;
};

const middleware3 = next => action => {
    console.log('middleware3 开始');
    const result = next(action);
    console.log('middleware3 结束');
    return result;
};

// 使用 compose 组合这些中间件
const finalMiddleware = compose(middleware1, middleware2, middleware3);

// 测试组合后的函数
const originalDispatch = action => {
    console.log('原始 dispatch:', action)
    return 1;
};
const enhancedDispatch = finalMiddleware(originalDispatch);
// (...args) => a(b(...args))
// 第一次迭代，返回： (...args) => middleware1(middleware2(...args))
// 第二次迭代，返回： (...args) => middleware1(middleware2(middleware3(...args)))
// 最终执行结果： middleware1(middleware2(middleware3(originalDispatch({ type: 'TEST' }))))

enhancedDispatch({ type: 'TEST' });


{
    // 测试一级调用
    function middleware1Func(next) {
        return function (action) {
            console.log('middleware1 开始');
            const result = next(action);
            console.log('middleware1 结束', result);
            return result;
        }
    }
    // middleware1Func(originalDispatch)({ type: '一段' })
}

{
    // 测试二级调用, 已经看不懂了... 好复杂
    // (...args) => middleware1(middleware2(...args))
    const expandedFunc = (...args) => {
        // return middleware1(middleware2(...args))

        // return function (action) {
        //     console.log('middleware1 开始');
        //     const result = middleware2(...args)(action);
        //     console.log('middleware1 结束');
        //     return result;
        // }

        return function (action) {
            console.log('middleware1 开始');
            // 1. result估计还是一个函数，（参数...args）是一个数组，其实我们此处只需要取值args[0], 如果传入的是middleware2, 那么args[0]还是个闭包，如果传入的是originalDispatch, 那么args[0]就是一个直接调用的函数了
            // const result = middleware2(...args)(action);

            // 2. 再进一步拆解， 应该是这样，大概是这样吧/?
            console.log('middleware2 开始');
            const result = args[0](action);
            console.log('middleware2 结束');

            console.log('middleware1 结束');
            console.log("result是值还是函数呢？", result);

            return result;
        }
    };

    const enhancedDispatch = expandedFunc(originalDispatch);
    // enhancedDispatch({ type: 'TESTsb' });

    const enhancedDispatch2 = expandedFunc(middleware3);
    // enhancedDispatch2(originalDispatch)({ type: 'TESTsb' });
}

{
    // 掌握reduce
    function testReduce() {
        const arr = [1, 2, 3, 4, 5];
        const sum = arr.reduce((acumulator, currentState) => acumulator + currentState, 0);
        console.log(sum);
    }

    // testReduce();

    function testCompose() {
        // 让我们用具体的函数来演示
        const add1 = x => x + 1;           // 加1
        const multiply2 = x => x * 2;      // 乘2
        const addPrefix = x => `结果是: ${x}`; // 添加前缀

        // compose(addPrefix, multiply2, add1)
        const result = [addPrefix, multiply2, add1].reduce((a, b) => (...args) => a(b(...args)));
        // 第一次迭代，返回： (...args) => addPrefix(multiply2(...args))
        // 第二次迭代，a = (...args) => addPrefix(multiply2(...args))  b = add1, 返回： (...args) => addPrefix(multiply2(add1(...args)))
        // 最终执行结果：addPrefix(multiply2(add1(1)))
        console.log(result(1));
    }

    // testCompose();
}

